package scheduler.controller;

import org.mybeans.dao.DAOException;

import scheduler.databean.Course;
import scheduler.databean.Lecture;
import scheduler.databean.Schedule;
import scheduler.databean.Section;
import scheduler.databean.User;
import scheduler.model.CourseDao;
import scheduler.model.LectureDao;
import scheduler.model.Model;
import scheduler.model.ScheduleDao;
import scheduler.model.SectionDao;


public class ScheduleTable {

	
		private ScheduleDao scheduleDao;
		private CourseDao courseDao;
		private SectionDao sectionDao;
		private LectureDao lectureDao;
		private int numDays = 5;
		private int numBlocks = 26;

		public ScheduleTable(Model model) {
			scheduleDao = model.getScheduleDao();
			courseDao = model.getCourseDao();
			sectionDao = model.getSectionDao();
			lectureDao = model.getLectureDao();
		}

		
	    
		public int calStartBlock(String startTime) {
	        return (Integer.parseInt(startTime.substring(0, 2)) - 8) * 2 + (startTime.substring(2).equals("30")? 1 : 0) - 1;
		}
		
		public int dayToInt(char day) {
	        switch (day) {
	            case 'M': return 0;
	            case 'T': return 1;
	            case 'W': return 2;
	            case 'R': return 3;
	            case 'F': return 4;
	            default : return -1;
	        }
		}
		
		public int[][] addTable(int[][] a, int[][] b) {
			for (int i = 0; i < numDays; i++) {
				for (int j = 0; j < numBlocks; j++) {
					a[i][j] += b[i][j];
				}
			}
			return a;
		}
		
		public int sum(int[] array) {
			int sum = 0;
			for (int i = 0; i < array.length; i++)
				sum += array[i];
			return sum;
		}
		
		public int[][] calTimeTable(String[] days, String[] startTime, int[] duration) {
			int[][] timeTable = new int[numDays][numBlocks];
			for (int i = 0; i < numDays; i++) {
				for (int j = 0; j < numBlocks; j++) {
					timeTable[i][j] = 0;
				}
			}

			for (int k = 0; k < days.length; k++) {
				for (int i = 0; i < days[k].length(); i++) {
					int day = dayToInt(days[k].charAt(i));
		
			        int startBlock = calStartBlock(startTime[k]);
			        int endBlock = startBlock + (duration[k] / 30) - 1;
			        
			        for (int j = startBlock; j <= endBlock; j++) {
			        	if (day != -1) // unsupported sunday
			        		timeTable[day][j]++;
			        }
				}
			}
			
			return timeTable;
		}
		
		public int[] columnSizes(Schedule[] schedule) {
			int[] columnSizes = new int[numDays];
			for (int i = 0; i < numDays; i++) {
				columnSizes[i] = 1;
			}
			
			if (schedule.length == 0)
				return columnSizes;
			
			int[][] timeTable = new int[numDays][numBlocks];
			for (int i = 0; i < numDays; i++) {
				for (int j = 0; j < numBlocks; j++) {
					timeTable[i][j] = 0;
				}
			}
			
			for (int i = 0; i < schedule.length; i++) {
				try {
					Section section = sectionDao.lookup(schedule[i].getSectionId());
					
					timeTable = addTable(timeTable, calTimeTable(section.getDay(), section.getStartTime(), section.getDuration()));

					Lecture lecture = lectureDao.lookup(section.getLectureId());
					timeTable = addTable(timeTable, calTimeTable(lecture.getDay(), lecture.getStartTime(), lecture.getDuration()));
					// save all times together and figure how many overlaps
				} catch (DAOException e) {
					e.printStackTrace();
				}
			}
			
			for (int i = 0; i < numDays; i++) {
				int max = 1;
				for (int j = 0; j < numBlocks; j++) {
					if (timeTable[i][j] > max)
						max = timeTable[i][j];
					
				}
				columnSizes[i] = max;
			}

			return columnSizes;
		}
		
		public String[][] scheduleTable(int[] columnSizes, Schedule[] schedule) {
			int numColumn = sum(columnSizes);
			String[][] scheduleTable = new String[numColumn][numBlocks];
			for (int i = 0; i < numColumn; i++) {
				for (int j = 0; j < numBlocks; j++) {
					scheduleTable[i][j] = "empty";
				}
			}
			
			if (schedule.length == 0)
				return scheduleTable;
			
			for (int i = 0; i < schedule.length; i++) {
				try {
					Section section = sectionDao.lookup(schedule[i].getSectionId());
					Course course = courseDao.lookup(section.getCourseId());
					String courseNumber = course.getMajorNumber() + "-" + course.getLevelNumber();
					scheduleTable = addBlock(scheduleTable, columnSizes, courseNumber, section.getSectionName(), section.getClassroom(), section.getDay(), section.getStartTime(), section.getDuration());

					if (section.getLectureId() != -1) {
						Lecture lecture = lectureDao.lookup(section.getLectureId());
						scheduleTable = addBlock(scheduleTable, columnSizes, courseNumber, lecture.getLectureNumber(), lecture.getClassroom(), lecture.getDay(), lecture.getStartTime(), lecture.getDuration());
					}
				} catch (DAOException e) {
					e.printStackTrace();
				}
			}
			
			return scheduleTable;
		}
		
		public String[][] addBlock(String[][] table, int[] columnSizes, String courseNumber, String section, String[] classroom, String[] days, String[] startTime, int[] duration) {
			for (int l = 0; l < days.length; l++) {
				for (int i = 0; i < days[l].length(); i++) {
					int day = dayToInt(days[l].charAt(i));
			        
					if (day == -1) // unsupported sunday
						continue;
					
			        int columnOffset = 0;
			        for (int j = 0; j < day; j++) {
			        	columnOffset += columnSizes[j];
			        }
			        
			        int startBlock = calStartBlock(startTime[l]);
			        int endBlock = startBlock + (duration[l] / 30) - 1;
			        
			        int column = -1;
			        for (int j = columnOffset; j < columnOffset + columnSizes[day]; j++) {
				        boolean isEmpty = true;
				        for (int k = startBlock; k <= endBlock; k++) {
				        	if (! table[j][k].equals("empty")) {
				        		isEmpty = false;
				        		break;
				        	}
				        }
				        if (isEmpty) {
				        	column = j;
				        	break;
				        }
			        }
			        
			        for (int j = startBlock; j <= endBlock; j++) {
			        	if (j == startBlock)
			        		table[column][j] = (duration[l]/30) + "@" + courseNumber + " " + section + "@" + classroom[l];
			        	else
			        		table[column][j] = "rowspan";
			        }
				}
			}
			return table;
		}
		
		public String getColor(String courseNumber) {
			return Integer.toHexString(Integer.parseInt(courseNumber.substring(0, 2) + courseNumber.substring(3, 6)) * 167);
		}
		
	    public String drawSchedule(User user, int scheduleNum) {
			// Must be logged in for this one
	 
	    	String userName = user.getUserName();
	    	
	        try {
	        	String page = "";
	        	
	        	Schedule[] viewSchedule = scheduleDao.getSchedule(userName, scheduleNum);
	        	if (viewSchedule.length > 0)
	        		page += "<h2 class=\"scheduleTitle\">" + viewSchedule[0].getSemester() + " " + viewSchedule[0].getYear() + "</h2>\n";

	       		int[] columnSizes = columnSizes(viewSchedule);
		        	
	        	page += "<div id=\"scheduleDiv\">\n" +
	        			"<table id=\"scheduleTable\">\n" +
	        			"<thead>\n" +
	        			"<tr>\n" +
	        			"<th class=\"time\">&nbsp</td>\n" +
	        			"<th scope=\"col\" colspan=\"" + columnSizes[0] + "\">Monday</th>\n" +
	        			"<th scope=\"col\" colspan=\"" + columnSizes[1] + "\">Tuesday</th>\n" +
	        			"<th scope=\"col\" colspan=\"" + columnSizes[2] + "\">Wednesday</th>\n" +
	        			"<th scope=\"col\" colspan=\"" + columnSizes[3] + "\">Thursday</th>\n" +
	        			"<th scope=\"col\" colspan=\"" + columnSizes[4] + "\">Friday</th>\n" +
	        			"</tr>\n" +
	        			"</thead>\n" +
	        			"<tbody>\n" +
	        			"<tr class=\"evenhour\">\n" +
	        			"<td class=\"time\">8:00</td>\n" +
	        			"<td class=\"class\" colspan=\"" + columnSizes[0] + "\">&nbsp</td>\n" +
	        			"<td class=\"class\" colspan=\"" + columnSizes[1] + "\">&nbsp</td>\n" +
	        			"<td class=\"class\" colspan=\"" + columnSizes[2] + "\">&nbsp</td>\n" +
	        			"<td class=\"class\" colspan=\"" + columnSizes[3] + "\">&nbsp</td>\n" +
	        			"<td class=\"class\" colspan=\"" + columnSizes[4] + "\">&nbsp</td>\n" +
	        			"</tr>\n";
		        	
	        	String[][] scheduleTable = scheduleTable(columnSizes, viewSchedule);
	        	
	        	int numSum = sum(columnSizes);
	        	
	        	for (int i = 0; i < numBlocks; i++) {
		        	page += "<tr class=\"" + (((i+3)%4<2)? "odd" : "even") + "hour\">\n";
	        		if (i % 2 == 0) {
		        		page += "<td class=\"time\" rowspan=\"2\">"+((i<8)?i/2+9:i/2-3)+":00</td>\n";
	        		}
	        		for (int j = 0; j < numSum; j++) {
	        			String blockInfo = scheduleTable[j][i];
	        			if (blockInfo.equals("empty")) {
	        				page += "<td>&nbsp</td>\n";
	        			}
	        			else if (! blockInfo.equals("rowspan")) {
	        				int firstSeparator = blockInfo.indexOf('@');
	        				int lastSeparator = blockInfo.lastIndexOf('@');
	        				String rowspan = blockInfo.substring(0, firstSeparator);
	        				String courseNumber = blockInfo.substring(firstSeparator + 1, lastSeparator);
	        				String classroom = blockInfo.substring(lastSeparator + 1);
	        				String link = courseNumber.substring(0, 2).concat(courseNumber.substring(3, 6));
	        				
	        				page += "<td class=\"class\" rowspan=\"" + rowspan + "\" style=\"background: #" + getColor(courseNumber) + "\">" +
	        						"<a href=\"schedule.do?which=" + link + "\" title=\"Click to switch sections for this course\">" +
	        						"<div class=\"courseNumber\">" + courseNumber + "</div>" +
	        						"<div class=\"classroom\">" + classroom + "</div>" +
	        						"</a></td>\n";
	        			}
	        		}
	        		page += "</tr>\n";
	        	}
	        	
	        	page += "<tr>\n" +
     					"<td class=\"time\"></td>\n" +
     					"<td colspan=\"" + columnSizes[0] + "\"></td>\n" +
     					"<td colspan=\"" + columnSizes[1] + "\"></td>\n" +
     					"<td colspan=\"" + columnSizes[2] + "\"></td>\n" +
     					"<td colspan=\"" + columnSizes[3] + "\"></td>\n" +
     					"<td colspan=\"" + columnSizes[4] + "\"></td>\n" +
     					"</tr>\n" +
     					"</tbody>\n" +
	        			"</table>\n" +
	        			"</div>\n";
        		
	        	return page;
	        	
			} catch (DAOException e) {
	        	return null;
			}
	    }
	}

	
	
	
	

